home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / os2 / octa209s.zip / octave-2.09 / liboctave / Array-idx.h < prev    next >
C/C++ Source or Header  |  1997-05-19  |  5KB  |  263 lines

  1. // Template array classes
  2. /*
  3.  
  4. Copyright (C) 1996 John W. Eaton
  5.  
  6. This file is part of Octave.
  7.  
  8. Octave is free software; you can redistribute it and/or modify it
  9. under the terms of the GNU General Public License as published by the
  10. Free Software Foundation; either version 2, or (at your option) any
  11. later version.
  12.  
  13. Octave is distributed in the hope that it will be useful, but WITHOUT
  14. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  15. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  16. for more details.
  17.  
  18. You should have received a copy of the GNU General Public License
  19. along with Octave; see the file COPYING.  If not, write to the Free
  20. Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  21.  
  22. */
  23.  
  24. #include "Array-flags.h"
  25. #include "idx-vector.h"
  26. #include "lo-error.h"
  27.  
  28. template <class T>
  29. void
  30. Array<T>::clear_index (void)
  31. {
  32.   delete [] idx;
  33.   idx = 0;
  34.   idx_count = 0;
  35. }
  36.  
  37. template <class T>
  38. void
  39. Array<T>::set_index (const idx_vector& i)
  40. {
  41.   if (! idx)
  42.     idx = new idx_vector [max_indices];
  43.  
  44.   if (idx_count < max_indices)
  45.     {
  46.       idx[idx_count++] = i;
  47.     }
  48.   else
  49.     {
  50.       (*current_liboctave_error_handler)
  51.     ("invalid number of indices specified");
  52.  
  53.       clear_index ();
  54.     }
  55. }
  56.  
  57. template <class T>
  58. Array<T>
  59. Array<T>::value (void)
  60. {
  61.   Array<T> retval;
  62.  
  63.   idx_vector *tmp = get_idx ();
  64.   idx_vector idx = tmp[0];
  65.  
  66.   retval = index (idx);
  67.  
  68.   clear_index ();
  69.  
  70.   return retval;
  71. }
  72.  
  73. template <class T>
  74. Array<T>
  75. Array<T>::index (idx_vector& idx) const
  76. {
  77.   Array<T> retval;
  78.  
  79.   int len = length ();
  80.  
  81.   int n = idx.freeze (len, "vector", liboctave_pzo_flag);
  82.  
  83.   if (idx)
  84.     {
  85.       if (idx.is_colon_equiv (len))
  86.     {
  87.       retval = *this;
  88.     }
  89.       else if (n == 0)
  90.     {
  91.       retval.resize (0);
  92.     }
  93.       else if (len == 1 && n > 1
  94.            && idx.one_zero_only ()
  95.            && idx.ones_count () == n)
  96.     {
  97.       retval.resize (n, elem (0));
  98.     }
  99.       else
  100.     {
  101.       retval.resize (n);
  102.  
  103.       for (int i = 0; i < n; i++)
  104.         {
  105.           int ii = idx.elem (i);
  106.           retval.elem (i) = elem (ii);
  107.         }
  108.     }
  109.     }
  110.  
  111.   // idx_vector::freeze() printed an error message for us.
  112.  
  113.   return retval;
  114. }
  115.  
  116. template <class T>
  117. void
  118. Array<T>::maybe_delete_elements (idx_vector& idx)
  119. {
  120.   int len = length ();
  121.  
  122.   if (len == 0)
  123.     return;
  124.  
  125.   if (idx.is_colon_equiv (len, 1))
  126.     resize (0);
  127.   else
  128.     {
  129.       int num_to_delete = idx.length (len);
  130.  
  131.       if (num_to_delete != 0)
  132.     {
  133.       int new_len = len;
  134.  
  135.       int iidx = 0;
  136.  
  137.       for (int i = 0; i < len; i++)
  138.         if (i == idx.elem (iidx))
  139.           {
  140.         iidx++;
  141.         new_len--;
  142.  
  143.         if (iidx == num_to_delete)
  144.           break;
  145.           }
  146.  
  147.       if (new_len > 0)
  148.         {
  149.           T *new_data = new T [new_len];
  150.  
  151.           int ii = 0;
  152.           iidx = 0;
  153.           for (int i = 0; i < len; i++)
  154.         {
  155.           if (iidx < num_to_delete && i == idx.elem (iidx))
  156.             iidx++;
  157.           else
  158.             {
  159.               new_data[ii] = elem (i);
  160.               ii++;
  161.             }
  162.         }
  163.  
  164.           if (--rep->count <= 0)
  165.         delete rep;
  166.  
  167.           rep = new ArrayRep (new_data, new_len);
  168.  
  169.           set_max_indices (1);
  170.         }
  171.       else
  172.         (*current_liboctave_error_handler)
  173.           ("A(idx) = []: index out of range");
  174.     }
  175.     }
  176. }
  177.  
  178. // ??? FIXME ??? -- this does not handle assignment of empty vectors
  179. // to delete elements.  Should it?
  180.  
  181. template <class LT, class RT>
  182. int
  183. assign (Array<LT>& lhs, const Array<RT>& rhs)
  184. {
  185.   int retval = 1;
  186.  
  187.   idx_vector *tmp = lhs.get_idx ();
  188.  
  189.   idx_vector idx = tmp[0];
  190.  
  191.   int lhs_len = lhs.length ();
  192.   int rhs_len = rhs.length ();
  193.  
  194.   int n = idx.freeze (lhs_len, "vector", liboctave_pzo_flag,
  195.               liboctave_rre_flag);
  196.  
  197.   if (n != 0)
  198.     {
  199.       if (liboctave_rre_flag && (rhs_len == n || rhs_len == 1))
  200.     {
  201.       int max_idx = idx.max () + 1;
  202.       if (max_idx > lhs_len)
  203.         lhs.resize (max_idx, 0.0);
  204.     }
  205.  
  206.       if (rhs_len == n)
  207.     {
  208.       for (int i = 0; i < n; i++)
  209.         {
  210.           int ii = idx.elem (i);
  211.           lhs.elem (ii) = rhs.elem (i);
  212.         }
  213.     }
  214.       else if (rhs_len == 1)
  215.     {
  216.       RT scalar = rhs.elem (0);
  217.  
  218.       for (int i = 0; i < n; i++)
  219.         {
  220.           int ii = idx.elem (i);
  221.           lhs.elem (ii) = scalar;
  222.         }
  223.     }
  224.       else
  225.     {
  226.       (*current_liboctave_error_handler)
  227.         ("A(I) = X: X must be a scalar or a vector with same length as I");
  228.  
  229.       retval = 0;
  230.     }
  231.     }
  232.   else if (idx.is_colon ())
  233.     {
  234.       if (lhs_len == 0)
  235.     {
  236.       lhs.resize (rhs_len);
  237.  
  238.       for (int i = 0; i < rhs_len; i++)
  239.         lhs.elem (i) = rhs.elem (i);
  240.     }
  241.       else
  242.     (*current_liboctave_error_handler)
  243.       ("A(:) = X: A must be the same size as X");
  244.     }
  245.   else
  246.     {
  247.       (*current_liboctave_error_handler)
  248.     ("A([]) = X: X must also be an empty matrix");
  249.  
  250.       retval = 0;
  251.     }
  252.  
  253.   lhs.clear_index ();
  254.  
  255.   return retval;
  256. }
  257.  
  258. /*
  259. ;;; Local Variables: ***
  260. ;;; mode: C++ ***
  261. ;;; End: ***
  262. */
  263.